import React, {useState} from 'react';
import {makeStyles, withStyles} from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Collapse from '@material-ui/core/Collapse';
import IconButton from '@material-ui/core/IconButton';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
import FileCopyIcon from '@material-ui/icons/FileCopy';
import {indicatorResponseToQueryWrapper, populateIndicatorQueryData} from "../../../../../../ruleEngine/rulesGenerator";
import Backend from "../../../../../Backend/Backend";
import parse from "html-react-parser";
import SnackbarMessage from "../../../Common/Snackbar/SnackbarMessage";
import Typography from "@material-ui/core/Typography";
import Grid from "@material-ui/core/Grid";
import {
  Backdrop,
  Checkbox,
  CircularProgress,
  Divider,
  FormControlLabel,
  TablePagination,
  Tooltip
} from "@material-ui/core";
import PreviewViz from "../../Question/IndicatorCard/components/PreviewViz";
import IndicatorDescription from "../../Question/IndicatorCard/components/IndicatorDescription";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons";
import {getIndicatorDataForEdit} from "../../../../../../redux/reducers/editor";
import {createNewIndicatorRequest, selectDeselectIndicator} from "../../../../../../redux/reducers/gqiEditor";
import {useDispatch} from "react-redux";
import {useHistory} from "react-router-dom";
import {green} from "@material-ui/core/colors";

const useRowStyles = makeStyles(theme => ({
  root: {
    '& > *': {
      borderBottom: 'unset',
    },
  },
  radius: {
    borderRadius: theme.spacing(0, 0, 1, 1)
  }
}));

const GreenCheckbox = withStyles({
  root: {
    color: green[400],
    '&$checked': {
      color: green[600],
    },
  },
  checked: {},
})((props) => <Checkbox color="primary" {...props} />);


function Row(props) {
  const {indicator, classes, selectedIndicators} = props;
  const styles = useRowStyles();
  const dispatch = useDispatch();
  const history = useHistory();
  const [openUndo, setOpenUndo] = useState(false);
  const [expanded, setExpanded] = React.useState(false);
  const [visualizationDisplay, setVisualizationDisplay] = useState(false);
  const [scriptCodeData, setScriptCodeData] = useState(false);
  const [loading, setLoading] = useState(false);
  const [indicatorDescription, setIndicatorDescription] = useState({
    analysisMethod: "",
    analysisMethodParams: {},
    visualizationLibrary: "",
    visualizationType: "",
  });
  const [openViz, setOpenViz] = useState(false);
  const [infoMessage, setInfoMessage] = useState({
    message: "",
    type: "",
    error: false
  });


  const handleRequestIndicatorDetails = async () => {
    if (!expanded && !visualizationDisplay && !scriptCodeData) {
      generateDescription(indicator);
      setOpenViz(!openViz);
      setInfoMessage({
        ...infoMessage,
        message: "Visualization is loading!",
        type: "info",
        error: false
      });
      const vizQuery = indicatorResponseToQueryWrapper(indicator);
      await Backend.post("/AnalyticsEngine/GetIndicatorPreview", vizQuery)
        .then(response => {
          const unescapedVizCode = decodeURIComponent(response.data.visualizationCode);
          let objectData = parse(unescapedVizCode);
          let scriptData = objectData[1].props.dangerouslySetInnerHTML.__html;
          setScriptCodeData(scriptData);
          setVisualizationDisplay(parse(unescapedVizCode));
          setInfoMessage({
            ...infoMessage,
            message: "Visualization loaded!",
            type: "success",
            error: false
          });
        }, (error) => {
          console.log(error);
          setInfoMessage({
            ...infoMessage,
            message: "Error loading visualization",
            type: "error",
            error: true,
          });
        })
    }
    setExpanded(!expanded);
  }

  const generateDescription = async (indicator) => {
    if (indicator.indicatorType === "Basic Indicator") {
      let indicatorData = populateIndicatorQueryData(indicator);
      let analysisName = "";
      let library = "";
      let libraryType = "";
      await Backend.get(`/AnalyticsMethod/AnalyticsMethods/${indicatorData.analysisMethod.id}`).then(response => {
        analysisName = response.data.name;
      }, (error) => {
        console.log(error)
      })
      await Backend.get(`/AnalyticsEngine/GetVisualizations`)
        .then(response => {
          response.data.forEach(vizData => {
            if (vizData.id === indicatorData.vizMethodType.libraryId) {
              library = vizData.name;
              const {visualizationTypes} = vizData;
              visualizationTypes.forEach(type => {
                if (type.id === indicatorData.vizMethodType.typeId)
                  libraryType = type.name;
              })
            }
          })
          setIndicatorDescription({
            ...indicatorDescription,
            analysisMethod: analysisName,
            analysisMethodParams: indicatorData.analysisMethod.additionalParams,
            visualizationLibrary: library,
            visualizationType: libraryType,
          })
        }, (error) => {
          console.log(error)
        })
    }
  }

  const handleEditIndicator = async (indicator) => {
    setLoading(true);
    dispatch(getIndicatorDataForEdit(indicator));
    dispatch(createNewIndicatorRequest(indicator.indicatorType));
    setTimeout(() => {
      history.push("/basic");
    }, 2000)
  }


  const handleSelectIndicatorCard = () => {
    if (!selectedIndicators.some(ind => ind.id === indicator.id)) {
      setOpenUndo(true);
      setInfoMessage({
        ...infoMessage,
        message: "Indicator added to selection!",
        type: "success"
      });
    } else {
      setOpenUndo(true);
      setInfoMessage({
        ...infoMessage,
        message: "Indicator removed from selection!",
        type: "info"
      });
    }
    // setState({...state, [event.target.name]: event.target.checked});
    dispatch(selectDeselectIndicator(indicator));
  }

  return (
    <>
      <TableRow className={styles.root}>

        <TableCell align="center">
          <FormControlLabel control={
            <GreenCheckbox
              checked={selectedIndicators.some(ind => ind.id === indicator.id)}
              onChange={handleSelectIndicatorCard}
              name="checkedG"/>}
          />
        </TableCell>

        <TableCell>{indicator.indicatorType}</TableCell>

        <TableCell component="th" scope="row">
          {indicator.name}
        </TableCell>

        <TableCell align="center">
          <Tooltip arrow title={!expanded ? <Typography>Show visualization</Typography> :
            <Typography>Hide visualization</Typography>}>
            <IconButton size="small" onClick={handleRequestIndicatorDetails}>
              {expanded ? <KeyboardArrowUpIcon/> : <KeyboardArrowDownIcon/>}
            </IconButton>
          </Tooltip>
        </TableCell>

        {/*<TableCell align="center">*/}
        {/*  <Tooltip arrow title={<Typography>Clone and edit</Typography>}>*/}
        {/*    <IconButton color="primary" onClick={() => handleEditIndicator(indicator)}>*/}
        {/*      <FileCopyIcon fontSize="small"/>*/}
        {/*    </IconButton>*/}
        {/*  </Tooltip>*/}
        {/*</TableCell>*/}

      </TableRow>

      <TableRow>

      <TableCell style={{paddingBottom: 0, paddingTop: 0, backgroundColor: "#fff", color: "#000"}} colSpan={6}>
          <Collapse in={expanded} timeout="auto" unmountOnExit>
            <Box margin={1}>
              <Table size="small" aria-label="purchases">
                <TableBody>
                  <Grid container>
                    <Grid item xs>
                      <Divider/>
                    </Grid>
                  </Grid>
                  {!infoMessage.error ? (
                    <>
                      <Grid container style={{padding: 24}}>
                        <Grid item xs className={classes.gutterTop}>
                          {!visualizationDisplay && !scriptCodeData ? (
                            <Grid container direction="column" alignItems="center">
                              <CircularProgress className={classes.gutterTopBottom}/>
                              <Typography variant="overline" style={{color: "#000"}}>Loading Visualization</Typography>
                            </Grid>
                          ) : (
                            <PreviewViz
                              scriptCodeData={scriptCodeData}
                              visualizationDisplay={visualizationDisplay}
                            />
                          )}
                        </Grid>
                        <Grid item xs className={classes.gutterTopBottom}>
                          <Grid container direction="column">
                            <Grid item className={classes.gutterBottom}>
                              <Typography variant="h6" style={{color: "#000"}}>Indicator Details:</Typography>
                            </Grid>
                            <Grid item>
                              <IndicatorDescription
                                classes={classes}
                                indicatorDescription={indicatorDescription}
                              />
                            </Grid>
                          </Grid>
                        </Grid>
                      </Grid>
                    </>
                  ) : (
                    <Grid container direction="column" justify="center" alignItems="center">
                      <FontAwesomeIcon icon={faExclamationTriangle} size={"4x"} color="red"
                                       className={classes.gutterTopBottom}/>
                      <Typography variant="h5" style={{color: "#000"}} gutterBottom>
                        Error loading details, please retry.
                      </Typography>
                    </Grid>
                  )}
                </TableBody>
              </Table>
            </Box>
          </Collapse>
        </TableCell>

      </TableRow>

      {/* Feedback */}
      <SnackbarMessage
        message={<Typography component={'span'}>{infoMessage.message}</Typography>}
        type={infoMessage.type}
        openSnackbar={openViz}
        setOpenSnackbar={setOpenViz}
        duration={5000}
      />

      <SnackbarMessage
        message={<Typography component={'span'}>{infoMessage.message}</Typography>}
        type={infoMessage.type}
        openSnackbar={openUndo}
        setOpenSnackbar={setOpenUndo}
        duration={3000}
        buttonAction={handleSelectIndicatorCard}
        buttonMessage={"undo"}
      />

      <Backdrop className={classes.backdrop} open={loading}>
        <Grid container direction="column" justify="center" alignItems="center">
          <Grid item>
            <CircularProgress color="inherit" size={60}/>
          </Grid>
          <Grid item>
            <Grid container direction="column" alignItems="center">
              <Typography>Populating Indicator data...</Typography>
              <Typography>Please wait!</Typography>
            </Grid>
          </Grid>
        </Grid>
      </Backdrop>

    </>
  );
}

export default function ListOfSelectedIndicators(props) {
  const {indicatorDetails, classes, selectedIndicators, searchIndicator, indicatorType} = props;
  const [rowsPerPage, setRowsPerPage] = React.useState(5);
  const [page, setPage] = React.useState(0);
  const styles = useRowStyles();

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  return (
    <>
      <TableContainer component={Paper} className={styles.radius}>
        <Table size="small">

          <TableHead>
            <TableRow>
              <TableCell><b><span style={{marginLeft: 4}}>Select</span></b></TableCell>
              <TableCell><b>Type</b></TableCell>
              <TableCell><b>Indicator names</b></TableCell>
              <TableCell align="center"><b>Details</b></TableCell>
              {/*<TableCell align="center"><b>Customize</b></TableCell>*/}
            </TableRow>
          </TableHead>

          <TableBody>
            {indicatorDetails.map((indicator) => {
              let nameToSearch = indicator.name.toLowerCase();
              const found = nameToSearch.includes(searchIndicator);
              let indicatorTypeToSearch = indicator.indicatorType.includes(indicatorType);
              const foundType = indicatorType === "All" ? true : indicatorTypeToSearch;
              if (found && foundType) {
                return (
                  <Row selectedIndicators={selectedIndicators}
                       key={indicator.name}
                       classes={classes}
                       indicator={indicator}/>
                )
              } else return "";
            })}
          </TableBody>

        </Table>

        <TablePagination
          rowsPerPageOptions={[5, 10, 25]}
          component="div"
          count={indicatorDetails.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />

      </TableContainer>
    </>
  );
}
